package com.cloud.pole.msg.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ace.cache.api.CacheAPI;
import com.alibaba.fastjson.JSON;
import com.cloud.pole.common.constant.CacheConstant;
import com.cloud.pole.common.constant.CommonConstants;
import com.cloud.pole.common.exception.BaseException;
import com.cloud.pole.common.msg.ApiRestResponse;
import com.cloud.pole.common.util.DateUtils;
import com.cloud.pole.common.util.NumberUtils;
import com.cloud.pole.common.util.RegexUtils;
import com.cloud.pole.feign.IBaseUserService;
import com.cloud.pole.msg.biz.MsgVerfyMsgcodeBiz;
import com.cloud.pole.msg.biz.SmsTemplateBiz;
import com.cloud.pole.msg.config.SmsProperties;
import com.cloud.pole.msg.model.entity.MsgVerfyMsgcode;
import com.cloud.pole.msg.model.entity.MsgVerfyMsgcodeAdmin;
import com.cloud.pole.msg.model.entity.SmsTemplate;
import com.cloud.pole.msg.model.enums.SmsSendStatus;
import com.cloud.pole.msg.model.vo.VerifyCodeDayVo;
import com.cloud.pole.msg.model.vo.VerifyCodeVo;
import com.cloud.pole.msg.service.SmsSendService;
import com.cloud.pole.msg.service.VerifyCodeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

/*
*2019年1月17日
*cloud-msg
*author:frank-chen
*/
@Slf4j
@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {

	@Autowired 
	private IBaseUserService baseUserService;
	@Autowired
	private SmsTemplateBiz smsTemplateBiz;
	@Autowired
	private SmsProperties smsProperties;
	@Autowired
    private CacheAPI cacheAPI;
	@Autowired
	private SmsSendService smsSendService;
	@Autowired
	private MsgVerfyMsgcodeBiz msgVerfyMsgcodeBiz;
	
	@Override
	public Boolean getVerifyCode(String mobileArea, String mobile,  String templateKey)throws Exception {
		// TODO Auto-generated method stub
		String verifyCode = "";
		Boolean result = false;
		if(!RegexUtils.isMobileNo(mobile, mobileArea)) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "手机号格式错误");
		}
		//获取短信模板
		SmsTemplate smsTemplate = smsTemplateBiz.selectByTemplateKey(templateKey);
		if(smsTemplate == null || smsTemplate.getTemplateStatus() == 0) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "短信模板错误");
		}
		int userExists = smsTemplate.getUserExists().intValue();
		
		ApiRestResponse<Boolean> restResponse = baseUserService.checkUserExistsByMobile(mobileArea, mobile);
		if(restResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "检测用户是否存在异常");
		}
		boolean flag = restResponse.getData();
		//检测用户是否存在
		if(userExists == SmsTemplate.USER_EXISTS_YES) {
			if(!flag) {
	    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "用户不存在");
			}
		}
		else if(userExists == SmsTemplate.USER_EXISTS_NO) {
			if(flag) {
	    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "用户已存在");
			}
		}
		//发送短信
		String msgVerifyCodeKey  = CacheConstant.SERVICE_MSG_VERIFY_CODE_KEY + ":"  + mobileArea + mobile + "-" + smsTemplate.getTemplateKey();
		String msgVerifyCountKey = CacheConstant.SERVICE_MSG_VERIFY_COUNT_KEY + ":" + mobileArea + mobile;
		if(smsProperties.isIstest()) {
			//如果是测试，假发验证码123456
			verifyCode = MsgVerfyMsgcode.TEST_VERFY_CODE;
		}
		else {
			verifyCode = NumberUtils.getMsgCode();
		}
		//获得最近一天发送，1分钟只能获取一次
		String strVerifyCode = cacheAPI.get(msgVerifyCodeKey);
		String strVerifyCodeDay = cacheAPI.get(msgVerifyCountKey);
		VerifyCodeVo verifyCodeVo = new VerifyCodeVo();
		verifyCodeVo.setMobile(mobile);
		verifyCodeVo.setMobileArea(mobileArea);
		verifyCodeVo.setVerifyCode(verifyCode);
		verifyCodeVo.setLastTime(new Date());
		
		String strDate = DateUtils.formatDate(new Date(), "yyyyMMdd");
		VerifyCodeDayVo verifyCodeDayVo = new VerifyCodeDayVo();
		verifyCodeDayVo.setDate(strDate);
		verifyCodeDayVo.setGetCount(1);
		verifyCodeDayVo.setMobile(mobile);
		verifyCodeDayVo.setMobileArea(mobileArea);
		//正式环境需要验证
		if(!smsProperties.isIstest()) {
			if(!StringUtils.isEmpty(strVerifyCode)) {
				//判断是否1分钟内有记录
				VerifyCodeVo tempVerifyCodeDayVo = JSON.parseObject(strVerifyCode, VerifyCodeVo.class);
				long seconde = DateUtils.minusSeconds(tempVerifyCodeDayVo.getLastTime(), new Date(), true);
				if(seconde < 60) {
					throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "1分钟只能只能获取1次验证码");
				}
			}
			if(!StringUtils.isEmpty(strVerifyCodeDay)) {
				VerifyCodeDayVo tempVerifyCodeDayVo = JSON.parseObject(strVerifyCodeDay, VerifyCodeDayVo.class);
				int nGetCount = tempVerifyCodeDayVo.getGetCount();
				if(nGetCount >= smsProperties.getMaxTimes()) {
					throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "超过获取验证码的最大次数");
				}
				//隔天清0
				if(StringUtils.equals(tempVerifyCodeDayVo.getDate(), strDate)){
					verifyCodeDayVo.setGetCount(nGetCount + 1);
				}
			}
		}
		cacheAPI.set(msgVerifyCodeKey , verifyCodeVo, CacheConstant.SERVICE_MSG_VERIFY_CODE_EXPIRE);
		cacheAPI.set(msgVerifyCountKey , verifyCodeDayVo, CacheConstant.SERVICE_MSG_VERIFY_COUNT_EXPIRE);

		MsgVerfyMsgcode msgVerfyMsgcode = new MsgVerfyMsgcode();
		msgVerfyMsgcode.setCreateTime(new Date());
		msgVerfyMsgcode.setMobileArea(mobileArea);
		msgVerfyMsgcode.setUserMphone(mobile);
		msgVerfyMsgcode.setVerfyStr(verifyCode);
		msgVerfyMsgcode.setVerfyState((short) 0);
		msgVerfyMsgcode.setVerfyBusiDic(templateKey);
		msgVerfyMsgcodeBiz.insertSelective(msgVerfyMsgcode);
	
		if(!smsProperties.isIstest()) {
			String smsContent = smsTemplate.getSmsTemplate().replaceAll("#verifyCode#", verifyCode);
			SmsSendStatus smsSendStatus = smsSendService.sendSmsMsg(mobileArea, mobile, smsContent, templateKey);
			if(smsSendStatus.code == SmsSendStatus.SUBMIT_OK.code) {
				result = true;
			}
		}
		else {
			result = true;
		}
		return result;
	}


	@Override
	public Boolean checkVerifyCode(String mobileArea, String mobile, String templateKey, String verifyCode)
			throws Exception {
		// TODO Auto-generated method stub
		if(!RegexUtils.isMobileNo(mobile, mobileArea)) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "手机号格式错误");
		}
//		//获取短信模板
//		SmsTemplate smsTemplate = smsTemplateBiz.selectByTemplateKey(templateKey);
//		if(smsTemplate == null || smsTemplate.getTemplateStatus() == 0) {
//    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "短信模板错误");
//		}
		
		//从缓存里面获取
		String msgVerifyCodeKey  = CacheConstant.SERVICE_MSG_VERIFY_CODE_KEY + ":"  + mobileArea + mobile + "-" + templateKey;
		String strVerifyCode = cacheAPI.get(msgVerifyCodeKey);
		if(StringUtils.isEmpty(strVerifyCode)) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "验证码错误");
		}
		VerifyCodeVo tempVerifyCodeDayVo = JSON.parseObject(strVerifyCode, VerifyCodeVo.class);
		if(tempVerifyCodeDayVo == null || !StringUtils.equals(tempVerifyCodeDayVo.getVerifyCode(), verifyCode)) {
    		throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "验证码错误");
		}
		//删除缓存
		Long lCache = cacheAPI.remove(msgVerifyCodeKey);
		
		//更新数据库
		MsgVerfyMsgcode param = new MsgVerfyMsgcode();
		param.setMobileArea(mobileArea);
		param.setUserMphone(mobile);
		param.setVerfyStr(verifyCode);
		param.setVerfyState((short)0);
		param.setVerfyBusiDic(templateKey);
		List<MsgVerfyMsgcode> verfyMsgcodeList =  msgVerfyMsgcodeBiz.selectList(param);
		if(verfyMsgcodeList != null) {
			for(MsgVerfyMsgcode msgVerfyMsgcode : verfyMsgcodeList) {
				msgVerfyMsgcode.setVerfyState((short)1);
				msgVerfyMsgcode.setVerfyDate(new Date());
				msgVerfyMsgcodeBiz.updateSelectiveById(msgVerfyMsgcode);
			}			
		}
		return true;
	}
	
	
	@Override
	public PageInfo<MsgVerfyMsgcodeAdmin> selectPageVerfyMsgcodeAdminList(Map<String, Object> map, int pageNo, int pageSize) {
		PageHelper.startPage(pageNo, pageSize); 
    	List<MsgVerfyMsgcodeAdmin> list = msgVerfyMsgcodeBiz.selectPageVerfyMsgcodeAdminList(map);
    	PageInfo<MsgVerfyMsgcodeAdmin> page = new PageInfo<MsgVerfyMsgcodeAdmin>(list);
    	return page;
	}


	@Override
	public Boolean test() {
		// TODO Auto-generated method stub
		MsgVerfyMsgcode param = new MsgVerfyMsgcode();
		param.setMobileArea("86");
		param.setUserMphone("13755002297");
		List<MsgVerfyMsgcode> verfyMsgcodeList =  msgVerfyMsgcodeBiz.selectList(param);
		log.info(verfyMsgcodeList.toString());
		return null;
	}
}
